package tk.zater;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.Scanner;

import org.apache.log4j.Logger;
import org.aspectj.weaver.NewConstructorTypeMunger;

import tk.zater.CS.EsetVersionConfigeration;
import tk.zater.CS.FileName;
import tk.zater.CS.UserAccountManagermant;
import tk.zater.Util.FileDownloader;
import tk.zater.Util.VerGenerator;
import tk.zater.Util.fileinfoutil;

public class download implements Runnable {
	EsetVersionConfigeration evc;
	Logger logger = Logger.getLogger(download.class);
	VerGenerator vg;
	FileDownloader fw;
	String Account[] = UserAccountManagermant.getAccount();

	public download(EsetVersionConfigeration ex) {
		this.evc = ex;
		fw = new FileDownloader(evc);
		vg = new VerGenerator(evc);
		// TODO Auto-generated constructor stub
		Account = UserAccountManagermant.getAccount();
	}

	@Override
	public void run() {
		evc.status=0;
		Scanner scn = null;
		// System.out.println(new Date().toString() + "start update");
		File updatezater = new File(evc.absolutePath + "update.bak");
		updatezater.delete();
		updatezater = new File(evc.absolutePath + "update.ver");
		updatezater.delete();

		File verzater = new File(evc.absolutePath + "ver.zater");
		verzater.delete();

		File Updater = new File(evc.absolutePath + "update.bak");
		fw.download(evc.updateurl, verzater.getAbsolutePath(), Account);
		express();
		updatezater.renameTo(Updater);
		try {
			scn = new Scanner(Updater);
		} catch (FileNotFoundException e) {
			logger.error(evc.getVersionName() + "Update.ver解开失败");
		}
		logger.info(evc.getVersionName() + "unpack update.ver success");
		vg.openfile();
		while (true) {
			String p = scn.nextLine();
			if (p.startsWith("[")) {
				if ("[HOSTS]".equals(p) || ("[Expire]").equals(p) || ("[SETUP]").equals(p) || ("[PCUVER]".equals(p))) {
				} else {
					vg.write(p);
					break;
				}
			}
		}

		FileName tempery = new FileName();
		Field[] allFields = null;
		try {
			allFields = Class.forName("tk.zater.CS.FileName").getFields();
		} catch (ClassNotFoundException e) {
			logger.error("找不到FileName文件，请检查包是否损坏");
		}
		while (scn.hasNext()) {
			String nextLine = scn.nextLine();
			if (nextLine.startsWith("[")) {
				vg.write(nextLine);
				update(tempery);
				tempery = new FileName();
				continue;
			}
			if (nextLine.startsWith("version") || nextLine.startsWith("versionid") || nextLine.startsWith("build")
					|| nextLine.startsWith("file") || nextLine.startsWith("size")) {
				String splitinfo[] = nextLine.split("=");
				if (nextLine.startsWith("file")) {
					tempery.Url = splitinfo[1];
					String fileinfo[] = tempery.Url.split("/");
					tempery.filename = fileinfo[fileinfo.length - 1];
					vg.write("file="  + tempery.filename);

				} else {
					vg.write(nextLine);
					if (splitinfo[0].equals("size")) {
						tempery.size = Integer.parseInt(splitinfo[1]);
						continue;
					}
					for (int i = 0; i < allFields.length; i++) {
						if (allFields[i].getName().equals(splitinfo[0])) {
							try {
								allFields[i].set(tempery, splitinfo[1]);
							} catch (IllegalArgumentException ex) {
								logger.error(allFields[i].getGenericType());
								logger.error("error 1011:reflect fail.");
							} catch (IllegalAccessException ex) {
								logger.error("error 1012:reflect fail.");
							}
						}
					}

				}
			} else {
				vg.write(nextLine);
			}
		}
		update(tempery);
		evc.lastUpdate=new Date();
		logger.info("update success");
		vg.closefile();
		evc.status=1;
		if (!evc.updatetoHDDirectly) {
			new fileinfoutil(evc).writefile();
		}
	}

	private boolean checkthefile(FileName tempery) {
		File downloadfile = new File(fw.path(tempery.Url)).getAbsoluteFile();
		if (tempery.size == downloadfile.length()) {
			return true;
		} else {
			logger.info(Account[0] + "error.失效");
			UserAccountManagermant.removeAccount(Account[0]);
			logger.info("剩余" + UserAccountManagermant.userAccount.size() + "未测试的帐号");
			if (UserAccountManagermant.userAccount.size() == 0) {
				logger.info("尝试使用帐号更新软件更新序列号");
				new Userstrategy().dealProcess();
			}
			Account = UserAccountManagermant.getAccount();
			return false;
		}
	}

	public void express() {
		try {
			Process process = Runtime.getRuntime().exec("rar E " + evc.absolutePath + "ver.zater " + evc.absolutePath);
			while (process.isAlive()) {
			}
		} catch (IOException e) {
			logger.error("error 1006.install rar.安装rar。");
			logger.error("for ubuntu:sudo apt-get install rar");
		}

	}

	public void update(FileName tempery) {
		if (tempery.filename.matches("(eav|ess)_nt(32|64)_[^c]{1}[^h]{1}[^st]{1}.nup"))
			return;

		boolean flag = false;
		if (evc.nowlist.nowlist.containsKey(tempery.filename)) {
			flag = true;
			FileName tp = evc.nowlist.nowlist.get(tempery.filename);
			if (tp.checkthesame(tempery) == true) {
				tempery = new FileName();
				return;
			}
		}
		while (true) {
			logger.info(evc.getVersionName() + ":start download " + tempery);

			fw.download(tempery.Url, Account);
			if (checkthefile(tempery) == true) {
				if (evc.updatetoHDDirectly) {
					new fileinfoutil(evc).writefile();
				}
				break;
			}

		}
		if (flag == true) {
			evc.nowlist.nowlist.remove(tempery.filename);
		}
		evc.nowlist.nowlist.put(tempery.filename, tempery);

	}
}
